package com.twu.biblioteca;

import com.twu.biblioteca.menuoptions.UserDetailsHandler;

import java.util.ArrayList;

/**
 * Created by olga on 31/05/14.
 */
public class LibraryManager
{
    private ArrayList<LibraryItem> libraryItems = new ArrayList<LibraryItem>();

    private static final String TITLE_COLUMN_HEADER = "Title";
    private static final String AUTHOR_COLUMN_HEADER = "Author/Director";
    private static final String YEAR_COLUMN_HEADER = "Year";
    private static final String RATING_COLUMN_HEADER = "Rating";

    private static final String BOOK_ITEM_IDENTIFIER = "book";
    private static final String MOVIE_ITEM_IDENTIFIER = "movie";

    public static int maxBookTitleLength;
    public static int maxBookAuthorLength;

    private UserDetailsHandler userDetailsHandler;

    public ArrayList<LibraryItem> getLibraryItems()
    {
        return libraryItems;
    }

    public void setLibraryItems(ArrayList<LibraryItem> libraryItems)
    {
        if( libraryItems != null )
            this.libraryItems = libraryItems;
        else
            this.libraryItems = new ArrayList<LibraryItem>();
    }

    public void setUserDetailsHandler(UserDetailsHandler userDetailsHandler)
    {
        this.userDetailsHandler = userDetailsHandler;
    }

    /* This is a temporary (iteration1) solution to achieve a "predefined book list" requirement;
     * further on, if requirements change to load book list from a file or a database
     * this method is to be refactored and moved, */
    public static LibraryManager initialiseBookLibrary()
    {
        LibraryManager result = new LibraryManager();

        ArrayList<LibraryItem> itemArrayList = new ArrayList<LibraryItem>();

        itemArrayList.add(new Book("Dune", "Frank Herbert", "1965"));
        itemArrayList.add(new Book("Ender's Game", "Orson Scott Card", "1985"));
        itemArrayList.add(new Book("The Foundation Trilogy", "Isaac Asimov", "1951"));
        itemArrayList.add(new Book("Hitch Hiker's Guide to the Galaxy", "Douglas Adams", "1979"));
        itemArrayList.add(new Book("1984", "George Orwell", "1949"));
        itemArrayList.add(new Book("Stranger in a Strange Land", "Robert A Heinlein", "1961"));
        itemArrayList.add(new Book("Fahrenheit 451", "Ray Bradbury", "1954"));
        itemArrayList.add(new Book("Neuromancer", "William Gibson", "1984"));
        itemArrayList.add(new Book("2001: A Space Odyssey", "Arthur C Clarke", "1968"));
        itemArrayList.add(new Book("Do Androids Dream of Electric Sheep?", "Philip K Dick", "1968"));
        itemArrayList.add(new Book("I, Robot", "Isaac Asimov", "1950"));
        itemArrayList.add(new Book("Starship Troopers", "Robert A Heinlein", "1959"));

        itemArrayList.add(new Movie("X-Men: Days of Future Past", "Bryan Singer", "2014", "8.5"));
        itemArrayList.add(new Movie("The Avengers", "Joss Whedon", "2012", "8.2"));
        itemArrayList.add(new Movie("Iron Man Three", "Shane Black", "2013", "7.4"));
        itemArrayList.add(new Movie("Blade Runner", "Ridley Scott", "1982", "8.2"));

        result.setLibraryItems(itemArrayList);

        return result;
    }

    public ArrayList<LibraryItem> getCheckedInBookList()
    {
        return getCheckedInItemList(BOOK_ITEM_IDENTIFIER);
    }

    public ArrayList<LibraryItem> getCheckedInMovieList() { return getCheckedInItemList(MOVIE_ITEM_IDENTIFIER);}

    public boolean checkOutBook( String bookTitle, String bookAuthor, String bookYearPublished)
    {
        return changeItemStatus( getLibraryItemIndex(bookTitle, bookAuthor, bookYearPublished, BOOK_ITEM_IDENTIFIER), true) != null;
    }

    public boolean returnBook(String bookTitle, String bookAuthor, String bookYearPublished)
    {
        return changeItemStatus(getLibraryItemIndex(bookTitle, bookAuthor, bookYearPublished, BOOK_ITEM_IDENTIFIER), false) != null;
    }

    public boolean checkOutMovie(String movieTitle, String movieDirector, String movieReleaseYear)
    {
        return changeItemStatus( getLibraryItemIndex(movieTitle, movieDirector, movieReleaseYear, MOVIE_ITEM_IDENTIFIER), true) != null;
    }

    public boolean returnMovie(String movieTitle, String movieDirector, String movieReleaseYear)
    {
        return changeItemStatus( getLibraryItemIndex(movieTitle, movieDirector, movieReleaseYear, MOVIE_ITEM_IDENTIFIER), false) != null;
    }

    public void listMovies()
    {
        ArrayList<LibraryItem> checkedInList = getCheckedInMovieList();

        calculateMaxTitleAndCreatorLength(checkedInList);

        TerminalPrintUtility.printRowWithFourColumns(TITLE_COLUMN_HEADER, maxBookTitleLength, AUTHOR_COLUMN_HEADER,
                                                    maxBookAuthorLength, YEAR_COLUMN_HEADER, RATING_COLUMN_HEADER);
        for( LibraryItem movie : checkedInList )
        {
            TerminalPrintUtility.printRowWithFourColumns(movie.getTitle(), maxBookTitleLength,
                                                        movie.getCreator(), maxBookAuthorLength,
                                                        movie.getYear(), ((Movie)movie).getRate());
        }
    }

    public void listBooks()
    {
        ArrayList<LibraryItem> checkedInList = getCheckedInBookList();

        calculateMaxTitleAndCreatorLength(checkedInList);

        TerminalPrintUtility.printRowWithThreeColumns(TITLE_COLUMN_HEADER, maxBookTitleLength, AUTHOR_COLUMN_HEADER, maxBookAuthorLength, YEAR_COLUMN_HEADER);
        for( LibraryItem book : checkedInList )
        {
            TerminalPrintUtility.printRowWithThreeColumns(book.getTitle(), maxBookTitleLength, book.getCreator(), maxBookAuthorLength, book.getYear());
        }
    }

    public int getLibraryItemIndex(String title, String author, String yearPublished, String itemType)
    {
        LibraryItem libraryItem = new LibraryItem(title,author,yearPublished);
        libraryItem.setItemType(itemType);
        return getLibraryItems().indexOf(libraryItem);
    }

    public void calculateMaxTitleAndCreatorLength(ArrayList<LibraryItem> checkedInBooks)
    {
        int maxTitleLength = TITLE_COLUMN_HEADER.length();
        int maxAuthorLenth = AUTHOR_COLUMN_HEADER.length();
        for( LibraryItem item : checkedInBooks )
        {
            if( item.getTitleStringLength() > maxTitleLength )
                maxTitleLength = item.getTitleStringLength();
            if( item.getCreatorStringLength() > maxAuthorLenth )
                maxAuthorLenth = item.getCreatorStringLength();
        }
        this.maxBookTitleLength = maxTitleLength;
        this.maxBookAuthorLength = maxAuthorLenth;
    }

    private ArrayList<LibraryItem> getCheckedInItemList( String itemType )
    {
        ArrayList<LibraryItem> checkedInItemList = new ArrayList<LibraryItem>();
        for( LibraryItem item : libraryItems )
        {
            if( item.getItemType().equals(itemType) && !item.isCheckedOut() )
                checkedInItemList.add(item);
        }
        return checkedInItemList;
    }

    private LibraryItem changeItemStatus( int itemIndx, boolean newStatus  )
    {
        if( itemIndx == -1)
            return null;

        LibraryItem result = getLibraryItems().get(itemIndx).setCheckedOutStatus(newStatus);
        if( newStatus )
            userDetailsHandler.setCurrentUserAsCheckOutUser(result);
        return result;
    }
}
